﻿using System;
using System.Collections.Generic;
using DM4;
using DM4.InfoClasses;
using sscore;

namespace DMN_MailSender
{
    
    public class DMN_MailSender : DaemonBase, IDisposable   
    {
        private Worker _worker;      

        public DMN_MailSender()
        {
            ModuleCode = MailSenderConsts.ModuleCode;
            Description = "Spam module";
            Version = "1.0";
            Debug = true;
        }

        public override OperationResult Init(IDM4Core iCore, DmTaskParams param = null)
        {
            base.Init(iCore, param);

            WriteLog(String.Format("Initialize daemon [{0}]...", ModuleCode));
            WriteLog(String.Format("Initialize daemon [{0}] complete", ModuleCode));

            WriteLog("Initialize module, create worker instance");
            _worker = new Worker(WriteLog, OnWorkerResult, Core.GetSysParam(DM4Consts.ConnectionString));

            return new OperationResult { Result = DM4Consts.Ok };
        }

        public override OperationResult Start()
        {
            OperationResult or = new OperationResult { Result = DM4Consts.Ok, Message = "" };
            WriteLog(message: String.Format("Start daemon [{0}] ...", ModuleCode));
            base.Start();

            Status = DaemonStatus.Starting;
            try
            {
                WorkWithDbData db = new WorkWithDbData(Core.GetSysParam(DM4Consts.ConnectionString), WriteLog);
                _worker.Send(db.GetNotEndedMail());
                Status = DaemonStatus.Run;
            }
            catch (Exception ex)
            {
                WriteLog(String.Format("Error occurred while start [{0}] module. {1}{2}{1}{3}", ModuleCode, Environment.NewLine, ex.Message, ex.StackTrace), MessageType.Error);
                or.Result = DM4Consts.ErrorUnknown;
                or.Message = ex.Message;
                Status = DaemonStatus.Stop;
            }

            return or;
        }

        public override OperationResult Execute(string cmdName, object commandParameters)
        {
            OperationResult or = new OperationResult { Result = DM4Consts.Ok, Message = "" };

            if (cmdName.ToUpper() == MailSenderCommands.SendMail.ToUpper()) //старт рассылки новых писем
            {
                if (commandParameters is List<MailSenderParameters> || commandParameters is MailSenderParameters)
                {
                    try
                    {
                        if (commandParameters is List<MailSenderParameters>)
                            _worker.Start((List<MailSenderParameters>)commandParameters);
                        else 
                            _worker.Start(new List<MailSenderParameters> { (MailSenderParameters)commandParameters });
                    }
                    catch (Exception ex)
                    {
                        WriteLog(String.Format("Error occurred while Execute [{0}] module. {1}{2}{1}{3}", ModuleCode, Environment.NewLine, ex.Message, ex.StackTrace), MessageType.Error);
                        Status = DaemonStatus.Stop;
                    }
                }
                else
                {
                    or.Result = DM4Consts.ErrorUnknownEntity;
                    or.Message = "Invalid parameters type, must be passed List<MailSenderWorkerParameters> or MailSenderWorkerParameters class instance.";
                }
            }
            else
            {
                or.Result = DM4Consts.ErrorUnknownCommand;
                or.Message = "Invalid command name for MailSender.";
            }
            return or;
        }

        public void OnWorkerResult(WorkerResult wr)
        {
            WriteLog(String.Format("Mail send complete. Processed mail(s) [{0}], errors count [{1}]", wr.CompleteCount, wr.ErrorCount));
        }

        public override OperationResult Stop()
        {
            WriteLog(String.Format("Stop daemon [{0}] ...", ModuleCode));
            Status = DaemonStatus.Stopping;
            base.Stop();

            if (_worker != null)
            {
                _worker.Stop();
                _worker = null;
            }

            Status = DaemonStatus.Stop;
            return new OperationResult { Result = DM4Consts.Ok, Message = "" };
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
                if (_worker != null)
                {
                    _worker.Dispose();
                    _worker = null;
                }
        }
        ~DMN_MailSender()
        {
            Dispose(false);
        }
    }
}
